package com.lhd_gm.scheduledtasksystem.utils;

import io.micrometer.common.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;
import java.util.Set;

public class ShellScriptGenerator {

    private static final Logger logger = LoggerFactory.getLogger(ShellScriptGenerator.class);

    // 默认保存目录（可根据需要配置）
    private static final String DEFAULT_BASE_DIR = "ScheduledTaskSystem/src/main/resources/static/shell";

    // 允许的文件名正则（字母、数字、下划线、短横线、点）
    private static final String FILENAME_PATTERN = "^[a-zA-Z0-9_.-]+\\.sh$";

    // 默认文件权限（rwxr-xr-x）
    private static final String DEFAULT_PERMISSIONS = "rwxr-xr-x";

    /**
     * 生成Shell脚本文件
     * @param scriptName 脚本文件名（需以.sh结尾）
     * @param content 脚本内容
     * @return 生成的完整文件路径
     * @throws IllegalArgumentException 参数校验失败
     * @throws IOException 文件操作失败
     */
    public static String generateScript(String scriptName, String content)
            throws IllegalArgumentException, IOException {
        File scriptFile = new File(DEFAULT_BASE_DIR);
        String absoluteScriptPath = scriptFile.getAbsolutePath();
        return generateScript(scriptName, content, absoluteScriptPath);
    }

    /**
     * 生成Shell脚本文件（自定义保存目录）
     * @param scriptName 脚本文件名
     * @param content 脚本内容
     * @param baseDir 保存基础目录
     * @return 生成的完整文件路径
     */
    public static String generateScript(String scriptName, String content, String baseDir)
            throws IllegalArgumentException, IOException {
        // 参数校验
        validateInput(scriptName, content, baseDir);
        // 构建完整路径
        Path fullPath = buildFullPath(scriptName, baseDir);
        // 确保目录存在
        createDirectoriesIfNeeded(fullPath);
        // 写入文件内容
        writeFileContent(fullPath, content);
        // 设置文件权限
        setFilePermissions(fullPath);
        logger.info("Shell脚本生成成功：{}", fullPath);
        System.out.println(fullPath.toString());
        return fullPath.toString();
    }

    private static void validateInput(String scriptName, String content, String baseDir)
            throws IllegalArgumentException {
        if (StringUtils.isBlank(scriptName)) {
            throw new IllegalArgumentException("脚本名称不能为空");
        }
        if (!scriptName.matches(FILENAME_PATTERN)) {
            throw new IllegalArgumentException("无效的文件名格式，只允许字母、数字、下划线、短横线和点，且必须以.sh结尾");
        }
        if (StringUtils.isBlank(content)) {
            throw new IllegalArgumentException("脚本内容不能为空");
        }
        if (StringUtils.isBlank(baseDir)) {
            throw new IllegalArgumentException("保存目录不能为空");
        }
    }

    private static Path buildFullPath(String scriptName, String baseDir) {
        return Paths.get(baseDir, scriptName).normalize();
    }

    private static void createDirectoriesIfNeeded(Path fullPath) throws IOException {
        Path parentDir = fullPath.getParent();
        if (!Files.exists(parentDir)) {
            logger.debug("创建目录：{}", parentDir);
            Files.createDirectories(parentDir);
        }
    }

    private static void writeFileContent(Path fullPath, String content) throws IOException {
        // 添加Shebang如果不存在
        String finalContent = content.startsWith("#!") ? content : "#!/bin/bash\n\n" + content;

        logger.debug("写入文件内容到：{}", fullPath);
        Files.write(fullPath, finalContent.getBytes());
    }

    private static void setFilePermissions(Path fullPath) throws IOException {
        if (!isWindows()) {
            Set<PosixFilePermission> permissions = PosixFilePermissions.fromString(DEFAULT_PERMISSIONS);
            Files.setPosixFilePermissions(fullPath, permissions);
            logger.debug("设置文件权限：{}", DEFAULT_PERMISSIONS);
        }
    }

    private static boolean isWindows() {
        return System.getProperty("os.name").toLowerCase().contains("win");
    }
}
